package yqRouter

import (
	"encoding/json"
	"fmt"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"go-yuque/entity"
	webEntity "go-yuque/entity"
	"go-yuque/logger"
	"go-yuque/response"
	"go-yuque/yuque"
	"net/http"
	"os"
	"path/filepath"
	"strings"
)

func InitApiRouter(e *gin.Engine) {
	group := e.Group("/api")

	{
		group.GET("/injectYqCookie", injectYqCookie)
		group.GET("/getUserBooks", getUserBooks)
		group.GET("/getDocs", getDocs)
		group.POST("/downloadTocs", downloadTocs)
	}

}

func injectYqCookie(c *gin.Context) {
	// 将 yqCookie 保存到 session 中
	yqCookie := c.Query("yqCookie")
	if len(yqCookie) <= 0 {
		c.JSON(http.StatusOK, response.ResponseStruct{
			Code:    1,
			Message: "请输入yqCookie",
		})
		return
	}
	session := sessions.Default(c)
	session.Set("yqCookie", yqCookie)
	err := session.Save()
	if err != nil {
		msg := fmt.Sprintf("保存session失败:%v", err)
		logger.Errorf(msg)
		c.JSON(http.StatusOK, response.Error(msg))
		return
	}

	c.JSON(http.StatusOK, response.Success("保存成功"))
	return
}

func getUserBooks(c *gin.Context) {

	session := sessions.Default(c)
	yqCookieI := session.Get("yqCookie")
	yqCookie, ok := yqCookieI.(string)
	if !ok {
		c.JSON(http.StatusOK, response.Error("请先注入yqCookie"))
		return
	}

	// 获取用户所有的分类和书籍
	categoryBooksPt, err := yuque.GetUserAllCategoryBooks(yqCookie)
	if err != nil {
		logger.Errorf("获取用户所有的分类和书籍失败: %v", err)
		c.JSON(http.StatusOK, response.Error("获取用户所有的分类和书籍失败"))
		return
	}

	// 提取出需要的数据
	var userCategories []*entity.UserBook

	for _, category := range categoryBooksPt.Data {
		userCategory := &entity.UserBook{
			Id:   category.ID,
			Name: category.Name,
			Type: "category",
		}

		var userBooks []*entity.UserBook
		for _, book := range category.Books {
			loginUser := book.User.Login
			userBook := &entity.UserBook{
				Id:        book.ID,
				Name:      book.Name,
				Slug:      book.Slug,
				LoginUser: loginUser,
				Type:      "book",
			}
			userBooks = append(userBooks, userBook)
		}
		if len(userBooks) > 0 {
			userCategory.Children = userBooks
		}

		userCategories = append(userCategories, userCategory)
	}

	c.JSON(200, response.SuccessWithMessage(userCategories, "获取用户所有的分类和书籍成功"))
}

// 获取指定知识库中的文档
func getDocs(c *gin.Context) {
	session := sessions.Default(c)

	yqCookieI := session.Get("yqCookie")
	yqCookie, ok := yqCookieI.(string)
	if !ok {
		c.JSON(http.StatusOK, response.Error("请先注入yqCookie"))
		return
	}

	loginUser := c.Query("loginUser")
	slug := c.Query("slug")
	bookIdx := c.Query("bookIdx")
	if len(loginUser) <= 0 || len(slug) <= 0 || len(yqCookie) <= 0 || len(bookIdx) <= 0 {
		c.JSON(http.StatusOK, response.Error(fmt.Sprintf("必填参数为空,loginUser:%s,slug:%s,bookIdx:%s", loginUser, slug, bookIdx)))
		return
	}

	tocArr, bookTreeStr, err := yuque.GetAllDocsInBook(loginUser, slug, bookIdx, yqCookie)
	if err != nil {
		logger.Errorf("获取知识库中所有文档失败:%v", err)
		c.JSON(http.StatusOK, response.Error(fmt.Sprintf("获取知识库中所有文档失败,err:%v", err)))
		return
	}

	if len(tocArr) == 1 {
		tocRoot := tocArr[0]
		if tocRoot.UUID == "ROOT" {
			tocArr = tocRoot.Children
		}
	}

	if len(bookTreeStr) > 0 {
		bookTreeKey := fmt.Sprintf("bookTreeStr_%s", slug)
		session.Set(bookTreeKey, bookTreeStr)
		err := session.Save()
		if err != nil {
			err = fmt.Errorf("保存session失败:%v", err)
			logger.Errorf(fmt.Sprintf("%v", err))
		}
	}

	c.JSON(http.StatusOK, response.SuccessWithMessage(tocArr, "获取知识库中所有文档成功"))

}

// 下载文档
func downloadTocs(c *gin.Context) {
	session := sessions.Default(c)

	yqCookieI := session.Get("yqCookie")
	yqCookie, ok := yqCookieI.(string)
	if !ok {
		c.JSON(http.StatusOK, response.Error("请先注入yqCookie"))
		return
	}

	downloadReq := entity.DownloadTocsReqStruct{}
	err := c.ShouldBindBodyWithJSON(&downloadReq)
	if err != nil {
		c.JSON(http.StatusOK, response.Error(fmt.Sprintf("参数错误,%v", err)))
		return
	}

	if downloadReq.BookId <= 0 || downloadReq.BookSlug == "" || downloadReq.BookName == "" ||
		downloadReq.Tocs == nil || len(downloadReq.Tocs) <= 0 || downloadReq.CategoryName == "" {
		c.JSON(http.StatusOK, response.Error("参数错误"))
		return
	}
	bookTreeKey := fmt.Sprintf("bookTreeStr_%s", downloadReq.BookSlug)
	bookTreeO := session.Get(bookTreeKey)
	logger.Debugf("bookTree From Session[%s]: key:【%s】\n%s", session.ID(), bookTreeKey, bookTreeO)

	tocs := downloadReq.Tocs
	// 转 json
	tocsJson, err := json.Marshal(tocs)
	if err != nil {
		c.JSON(http.StatusOK, response.Error(fmt.Sprintf("tocs转JSON报错,%v", err)))
		return
	}

	bookName := fmt.Sprintf("%03s-%s", downloadReq.BookIdx, downloadReq.BookName)
	tocsR, err := yuque.DownloadDocs(downloadReq.CoverOldFiles, downloadReq.BookId,
		downloadReq.CategoryName, bookName, yqCookie, tocsJson)

	handleResult := strings.Builder{}
	if tocsR != nil && len(tocsR) > 0 {
		for _, tocR := range tocsR {
			handleResult.WriteString(fmt.Sprintf("%s:[%s]\\n", tocR.Title,
				strings.ReplaceAll(tocR.GetHandleResult(), "\n", "\\n")))
		}
	}

	// 如果需要打印知识库树形结构
	// if downloadReq.NeedPrintBookTree {
	baseDownloadPath := filepath.Join(webEntity.GetTargetDir(), downloadReq.CategoryName, bookName)

	bookTreeStr := session.Get(bookTreeKey)
	if bookTreeStr != nil && bookTreeStr != "" {
		// 知识库树形结构不为空
		// 清空写，无则创建
		bookTreeFile, errT := os.OpenFile(filepath.Join(baseDownloadPath, "知识库结构.txt"), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
		if errT != nil {
			logger.Errorf("创建知识库树形结构文件失败:%v", errT)

			if err == nil {
				err = errT
			}
			handleResult.WriteString("创建知识库树形结构文件失败\\n")
		}
		defer bookTreeFile.Close()
		bookTreeFile.WriteString(bookTreeStr.(string))
	}
	// }

	if err != nil {
		logger.Errorf("下载文档失败:%v", err)
		c.JSON(http.StatusOK, response.Error(fmt.Sprintf("<span style=\"color: orangered; font-weight: bolder\">下载文档失败</span>"+
			"\\n处理结果:\\n%s\\n<span style=\"color: orangered; font-weight: bolder\">error:%v</span>", handleResult.String(), err)))
		return
	}

	c.JSON(http.StatusOK, response.SuccessWithMessage(nil,
		fmt.Sprintf("<span style=\"color: dodgerblue; font-weight: bolder\">下载完成</span>"+
			"\\n处理结果:\\n%s", handleResult.String())))
}
